package _Pan3D.utils {
	import _Pan3D.base.Camera3D;
	import _Pan3D.base.Focus3D;
	import _Pan3D.display3D.Display3DContainer;
	import _Pan3D.program.Program3DManager;
	import _Pan3D.program.shaders.ScanningShader;
	
	import _Pan3D.core.MathCore;
	import _me.Scene_data;
	
	import com.adobe.utils.PerspectiveMatrix3D;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display3D.Context3D;
	import flash.display3D.Context3DProgramType;
	import flash.display3D.Context3DTriangleFace;
	import flash.display3D.Program3D;
	import flash.filters.BitmapFilterQuality;
	import flash.filters.BlurFilter;
	import flash.geom.Matrix3D;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.geom.Vector3D;

	/**
	 * @author MSN:liuyan3757@163.com  QQ: 421537900
	 */
	public class Scanning {
		private var program : Program3D;
		private var context : Context3D;

		public function Scanning() {
			init();
		}

		private function init() : void {
			context = Scene_data.context3D;
			program = Program3DManager.getInstance().getProgram(ScanningShader.SCANNINGSHADER);
			// program = context.createProgram();
			// program.upload(Scene_data.shaderDictionary["scanning"][0], Scene_data.shaderDictionary["scanning"][1]);
		}

		public function scan(scanTarget : Display3DContainer, program : Program3D = null) : BitmapData {
			this.program = program;

			var cam3d : Camera3D = Scene_data.cam3D.clone();
			var focus3D : Focus3D = Scene_data.focus3D.cloneFocus3D();
			// Scene_data.focus3D=new Focus3D();
			Scene_data.cam3D.distance = Scene_data.scanningHight;
			Scene_data.cam3D.angle_y = 0;
			Scene_data.cam3D.fovw = 1024;
			Scene_data.cam3D.fovh = 1024;
			Scene_data.focus3D.angle_x = -90;
			Scene_data.focus3D.angle_y = 0;
			Scene_data.focus3D.y = 0;
			Scene_data.laseScanningPesition.x = Scene_data.focus3D.x;
			Scene_data.laseScanningPesition.y = Scene_data.focus3D.y;
			Scene_data.laseScanningPesition.z = Scene_data.focus3D.z;

			MathCore._catch_cam(Scene_data.cam3D, Scene_data.focus3D);

			//var lastProgram : Program3D = scanTarget.program;
			Scene_data.context3D.configureBackBuffer(1024, 1024, 1, true);
			context.clear(0, 0, 0, 1);
			var projMatrix : PerspectiveMatrix3D = new PerspectiveMatrix3D();
			projMatrix.perspectiveFieldOfViewRH(0.93, 1, 0.1, 90000);

			var vectorData : Vector.<Number>=new Vector.<Number>;
			vectorData.push(512, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
			var dataMatrix : Matrix3D = new Matrix3D(vectorData);
			context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 8, dataMatrix, true);

			context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 5, Vector.<Number>([256, 1, 0.5, 0]));
			context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, projMatrix, true);
			//scanTarget.setProgram3D(program);
			scanTarget.updateForScanning(program);
			// context.present();
			var bitmapdata : BitmapData = new BitmapData(1024, 1024);
			context.drawToBitmapData(bitmapdata);
			//scanTarget.setProgram3D(lastProgram);

			Scene_data.cam3D = cam3d;
			Scene_data.focus3D = focus3D;
			Scene_data.context3D.configureBackBuffer(1024, 600, 1, true);

			return bitmapdata;
		}
		private var tempNum:int;
		public function scanShadow(scanTarget : Display3DContainer, program : Program3D = null) : BitmapData {
			this.program = program;

			/*var cam3d : Camera3D = Scene_data.cam3D.clone();
			var focus3D : Focus3D = Scene_data.focus3D.cloneFocus3D();
			Scene_data.cam3D.distance = Scene_data.scanningHight;
			Scene_data.cam3D.angle_y = 0;
			Scene_data.cam3D.fovw = 1024;
			Scene_data.cam3D.fovh = 1024;
			Scene_data.focus3D.angle_x = -90;
			Scene_data.focus3D.angle_y = 0;
			Scene_data.focus3D.y = 0;
			Scene_data.laseScanningPesition.x = Scene_data.focus3D.x;
			Scene_data.laseScanningPesition.y = Scene_data.focus3D.y;
			Scene_data.laseScanningPesition.z = Scene_data.focus3D.z;

			MathCore._catch_cam(Scene_data.cam3D, Scene_data.focus3D);
				
			tempNum += 10;*/
			
			Scene_data.cam3D.cameraMatrix.identity();
			Scene_data.cam3D.cameraMatrix.prependTranslation(0, 0, -4000);
			Scene_data.cam3D.cameraMatrix.prependRotation(120, new Vector3D(1, 0, 0));
			//Scene_data.cam3D.cameraMatrix.prependRotation(30, new Vector3D(0, 1, 0));
			Scene_data.cam3D.cameraMatrix.prependTranslation(0, 0, 0);

			var lastProgram : Program3D = scanTarget.program;
			Scene_data.context3D.configureBackBuffer(1024, 1024, 1, true);
			//context.setRenderToTexture(Scene_data.texShadowMap, false, 16, 0);
			context.clear(1, 1, 1, 1);
			context.setCulling(Context3DTriangleFace.NONE);	
			var projMatrix : PerspectiveMatrix3D = new PerspectiveMatrix3D();
			projMatrix.perspectiveFieldOfViewRH(0.928, 1, 0.1, 90000);

			/*var vectorData : Vector.<Number>=new Vector.<Number>;
			vectorData.push(2048, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
			var dataMatrix : Matrix3D = new Matrix3D(vectorData);
			context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 8, dataMatrix, true);*/

			context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, projMatrix, true);
			context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 2, Vector.<Number>([0.5, 0.5, 0.5, 0]));
			scanTarget.setProgram3D(program);
			scanTarget.update();
			
			context.setRenderToBackBuffer();
			//	context.present();

			var bitmapdata : BitmapData = new BitmapData(1024, 1024);
			context.drawToBitmapData(bitmapdata);
			scanTarget.setProgram3D(lastProgram);

		//	Scene_data.cam3D = cam3d;
		//	Scene_data.focus3D = focus3D;
			Scene_data.context3D.configureBackBuffer(1024, 600, 1, true);
			
			var filter:BlurFilter = new BlurFilter(3,3,BitmapFilterQuality.HIGH);
			bitmapdata.applyFilter(bitmapdata,new Rectangle(0,0,bitmapdata.width,bitmapdata.height),new Point,filter);
			Scene_data.texShadowMap.uploadFromBitmapData(bitmapdata);
			
			return bitmapdata;
		}
	}
}